<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>
	<title>Working with controllers</title>
  <link rel="stylesheet" type="text/css" href="documentation.css" />
</head>
<body>
<h1>Working with controllers</h1>
<h2>What is a controller</h2>
<p>The aim of Konstrukt is to provide a solid foundation for building web applications, and the basic building block are the controllers. So what is a controller? Briefly spoken, a controller is a class, with a method on it that is invoked and as a response either returns a string or throws a <code>http_Response</code>.</p>
<p>If a string is returned, it is normal output, and should be output at the end of the script. The other possibility -- throwing of a <code>http_Response</code> is used for abnormal responses, such as the infamous <em>404 Not Found</em> or redirects. As such, a controller is a class which does the same as a traditional PHP script. And that&#039;s the point exactly; The controller provides an encapsulated interface for writing scripts that reacts to user input.</p>
<p>Just like the output is well defined for a controller, so is the input. A controller gets its input from its <code>context</code>. To begin with, the context is a <code>http_Request</code> -- An object, which encapsulates the request for the script. This forms a closure over a variety of otherwise global variables, including <code>$_GET</code> and <code>$_POST</code>.</p>
<h2>Creating a new project</h2>
<p>Before we look further at controllers, we&#039;ll do a bit of footwork to set up for loading libraries etc. You are quite free to bootstrap your application as you see fit, but the easiest way to get started with a new application, is to take a copy of the <code>blank_project</code> folder from the distribution of Konstrukt.</p>
<p>Assuming that your web root is at <code>C:\wamp\www</code>, create a new folder here, called <code>C:\wamp\www\konstrukt</code> and unpack the complete distribution into it. Next take a copy of the directory <code>C:\wamp\www\konstrukt\blank_project</code> to <code>C:\wamp\www\konstrukt\foo</code> for our application &quot;foo&quot;.</p>
<div class="note">Note: For the purpose of this article, we&#039;ll just create our application in an obscure subdirectory. When deploying a real application, it&#039;s easy to relocate the project.</div>
<p><code>blank_project</code> is a basic setup, which contains a simple directory structure, and other things that you need to begin a web application. There are two folders in there - <code>www</code> which should be the web root of your site and <code>lib</code> which should contain the classes of your application. Once you&#039;re set up, the <code>www</code> folder isn&#039;t used much. The bootstrap file <code>C:\wamp\www\konstrukt\foo\index.php</code> takes care of dispatching to the controller layer.</p>
<p>You can now open your browser and go to <code>http://localhost/konstrukt/foo/www</code> and verify that everything is in order. The following message should meet you if everything is running correctly :</p>
<div class="nostyle">  <h1>Root</h1>
  <p>This page is intentionally left blank</p></div>
<p>This is the output of the dispatchers <code>GET()</code> function. You can change this by opening the file <code>C:\wamp\www\konstrukt\foo\lib\root.php</code> and edit the function <code>GET()</code>.</p>
<div class="note">Note: The dispatcher is the first controller, which is invoked. This is normally named <code>Root</code>, and hence referred to as the root-controller. It is somewhat analogous to a the front controller pattern, which you may or may not be familiar with.</div>
<h2>Adding URLs</h2>
<p>To add a new URL to your application, you should first create a new class, which extends from <code>k_Controller</code>, and implements <code>GET()</code>.<br />
Create a file with the following contents and save it as <code>C:\wamp\www\konstrukt\foo\lib\mypage.php</code></p>
<pre class="php"><span class="kw2">class</span> MyPage <span class="kw2">extends</span> k_Controller
<span class="br0">&#123;</span>
  <span class="kw2">function</span> GET<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">return</span> <span class="st0">&quot;Hello World&quot;</span>;
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre><p>To make your newly created controller available, you have to add the URL-name as key and classname as value into the <code>$map</code> property of the root controller. Open up <code>C:\wamp\www\konstrukt\foo\lib\root.php</code> and add the following:</p>
<pre class="php"><span class="kw2">class</span> Root <span class="kw2">extends</span> k_Dispatcher
<span class="br0">&#123;</span>
  <span class="kw2">public</span> <span class="re0">$map</span> = <span class="kw3">Array</span><span class="br0">&#40;</span>
    <span class="st0">'hello'</span> =&gt; <span class="st0">'MyPage'</span>
  <span class="br0">&#41;</span>;
...</pre><p>You can now navigate to the following location:<br />
<code>http://localhost/konstrukt/foo/www/hello</code></p>
<p>And you should get the output from MyPage (&quot;Hello World&quot;).</p>
<h2>Controller lifecycle</h2>
<p class="illustration"><img src="controller-lifecycle.png" alt="controller-lifecycle.png" /></p><p>A controller begins execution when its <code>handleRequest()</code> method is called. Here, the URL subspace is inspected, and control is either dispatched to <code>execute()</code> or to <code>forward()</code>.</p>
<p>While <code>handleRequest()</code> is the entry point of the controller, <code>execute()</code> is where the action happens. The standard implementation of <code>execute()</code> further delegates to a method corresponding to the HTTP-method of the request. In particular, <code>GET()</code> is the most important to consider.</p>
<p>The default <code>forward()</code> implementation is fairly static - it uses an associative array (<code>$map</code>) to determine the classname of the child controller.</p>
<h2>Forwarding intelligently</h2>
<p>Some times, you need a bit more dynamics into your site, than what the default <code>forward()</code> method offers. For example, take the following two URLs:</p>
<p><code>http://example.org/articles/how-to-get-rich-in-four-easy-steps</code><br />
<code>http://example.org/articles/learn-c-plus-plus-in-21-days</code></p>
<p>In this case, the two URLs should be handled by the same controller, but the name of the controller isn&#039;t on the URL. To implement this, you could create two controllers - one for the articles-part of the URL, and one for showing an article by its name:</p>
<p>First, we modify the root controller to forward <code>/articles</code> to our controller named <code>Articles</code>.</p>
<pre class="php"><span class="kw2">class</span> Root <span class="kw2">extends</span> k_Dispatcher
<span class="br0">&#123;</span>
  <span class="kw2">public</span> <span class="re0">$map</span> = <span class="kw3">Array</span><span class="br0">&#40;</span>
    <span class="st0">'articles'</span> =&gt; <span class="st0">'Articles'</span>
  <span class="br0">&#41;</span>;
<span class="br0">&#125;</span></pre><p>Next, we create the controller for handling requests, which goes to <code>/articles</code>:</p>
<pre class="php"><span class="kw2">class</span> Articles <span class="kw2">extends</span> k_Controller
<span class="br0">&#123;</span>
  <span class="co1">// called if the URL has any names left on the subspace</span>
  <span class="co1">// Eg. anything right of http://example.org/articles/</span>
  <span class="kw2">function</span> forward<span class="br0">&#40;</span><span class="re0">$name</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="re0">$next</span> = <span class="kw2">new</span> Articles_Show<span class="br0">&#40;</span><span class="re0">$this</span>, <span class="re0">$name</span><span class="br0">&#41;</span>;
    <span class="kw1">return</span> <span class="re0">$next</span>-&gt;<span class="me1">handleRequest</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre><p>The important deviance from other controller, we have seen thus far, is in the <code>forward()</code> method. Note how <code>Articles_Show</code> is used, regardless of what the name is.</p>
<p>Finally, the controller which handles the display of an article. The controller knows which name was used to identify it in the context (the <code>Articles</code> controller); this information is available in the <code>$name</code> property.</p>
<pre class="php"><span class="kw2">class</span> Articles_Show <span class="kw2">extends</span> k_Controller
<span class="br0">&#123;</span>
  <span class="co1">// $this-&gt;name contains the URL &quot;name&quot;, which the parent controller</span>
  <span class="co1">// used to forward to this one.</span>
  <span class="co1">// Eg. the name right of http://example.org/articles/</span>
  <span class="kw2">function</span> GET<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="re0">$article</span> = <span class="re0">$this</span>-&gt;<span class="me1">registry</span>-&gt;<span class="me1">articles</span>-&gt;<span class="me1">getByName</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">name</span><span class="br0">&#41;</span>;
    <span class="kw1">if</span> <span class="br0">&#40;</span>!<span class="re0">$article</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
      <span class="kw1">throw</span> <span class="kw2">new</span> k_http_Response<span class="br0">&#40;</span><span class="nu0">404</span><span class="br0">&#41;</span>;
    <span class="br0">&#125;</span>
    <span class="kw1">return</span> <span class="re0">$this</span>-&gt;<span class="me1">render</span><span class="br0">&#40;</span><span class="st0">&quot;templates/show-articles.tpl.php&quot;</span>, <span class="re0">$article</span><span class="br0">&#41;</span>;
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre><p>For this example, we assume a model component <code>$this-&gt;registry-&gt;articles</code>, which has a method <code>getByName</code>, which retrieves an article, based on its name. We further assume a template in the location <code>templates/show-articles.tpl.php</code>. These are left to the readers imagination.</p>
<h2>Using the hierarchy</h2>
<p>We can further round off the application, by implementing a <code>GET()</code> method on <code>Articles</code> and <code>Root</code>. These will handle the URLs <code>/articles</code> and <code>/</code> respectively.</p>
<pre class="php"><span class="kw2">class</span> Articles <span class="kw2">extends</span> k_Controller
<span class="br0">&#123;</span>
  <span class="co1">// called if the URL http://example.org/articles is called directly</span>
  <span class="kw2">function</span> GET<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">return</span> <span class="re0">$this</span>-&gt;<span class="me1">render</span><span class="br0">&#40;</span><span class="st0">&quot;templates/list-articles.tpl.php&quot;</span><span class="br0">&#41;</span>;
  <span class="br0">&#125;</span>
...</pre><pre class="php"><span class="kw2">class</span> Root <span class="kw2">extends</span> k_Dispatcher
<span class="br0">&#123;</span>
  <span class="co1">// called if the URL http://example.org/ is called directly</span>
  <span class="kw2">function</span> GET<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">return</span> <span class="re0">$this</span>-&gt;<span class="me1">render</span><span class="br0">&#40;</span><span class="st0">&quot;templates/root.tpl.php&quot;</span><span class="br0">&#41;</span>;
  <span class="br0">&#125;</span>
...</pre><p>Again, we&#039;ll leave the actual implementation of the templates for now.</p>
<p>As a side effect of the fact that controllers forwards in a hierarchy, the controllers which forwards to child controllers can decorate the output of these. Taking the running example -- If you make a slight adjustment to the <code>Articles</code> class, you could have it render a wrap around the <code>Articles_Show</code> output. This is perfect for rendering menus, navigation etc.:</p>
<pre class="php"><span class="kw2">class</span> Articles <span class="kw2">extends</span> k_Controller
<span class="br0">&#123;</span>
  <span class="co1">// called if the URL has any names left on the subspace</span>
  <span class="co1">// Eg. anything right of http://example.org/articles/</span>
  <span class="kw2">function</span> forward<span class="br0">&#40;</span><span class="re0">$name</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="re0">$next</span> = <span class="kw2">new</span> Articles_Show<span class="br0">&#40;</span><span class="re0">$this</span>, <span class="re0">$name</span><span class="br0">&#41;</span>;
    <span class="kw1">return</span> <span class="re0">$this</span>-&gt;<span class="me1">wrap</span><span class="br0">&#40;</span><span class="re0">$next</span>-&gt;<span class="me1">handleRequest</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
  <span class="br0">&#125;</span>
&nbsp;
  <span class="kw2">protected</span> <span class="kw2">function</span> wrap<span class="br0">&#40;</span><span class="re0">$html</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">return</span> <span class="st0">&quot;&lt;div id='articles'&gt;&quot;</span>.<span class="re0">$html</span>.<span class="st0">&quot;&lt;/div&gt;&quot;</span>;
  <span class="br0">&#125;</span>
...</pre><h2>Request data</h2>
<p>While the <em>path</em> element of the URL is the most important part of the incoming request, there are other parameters of interest. The simplest, and commonly used is the querystring; Otherwise known as GET parameters. PHP parses these parameters and make them available in the superglobal variable <code>$_GET</code>. Because global variables have a tendency to make applications very messy, Konstrukt provides an encapsulation, so you don&#039;t have to use <code>$_GET</code> directly. Additionally, this protects you from incompatibilities with the dreaded <em>magic_quotes</em> setting, and translates UTF-8 encoded input data for you. To access the GET-parameters <code>foo</code>, you should simply use <code>$this-&gt;GET[&#039;foo&#039;]</code> in your controllers. This is analogous to using <code>$_GET[&#039;foo&#039;]</code>, which you should <strong>never</strong> do.</p>
<p>Konstrukt further provides access to standard POST&#039;ed data with <code>$this-&gt;POST</code>, as well as request headers in <code>$this-&gt;HEADERS</code>, and the less commonly used <code>$this-&gt;FILES</code>, <code>$this-&gt;ENV</code>, and <code>$this-&gt;INPUT</code>. The latter contains the raw content of the request, which will normally only be populated in a POST request.</p>
<p>Konstrukt also offers an encapsulation of session variables. Sessions are used in the following way:</p>
<pre class="php"><span class="kw2">class</span> MyController
<span class="br0">&#123;</span>
  <span class="kw2">function</span> GET<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="re0">$foo</span> =&amp; <span class="re0">$this</span>-&gt;<span class="me1">session</span>-&gt;<span class="me1">get</span><span class="br0">&#40;</span><span class="st0">&quot;foo&quot;</span><span class="br0">&#41;</span>; <span class="co1">// $foo is an array</span>
    <span class="re0">$foo</span><span class="br0">&#91;</span><span class="st0">'bar'</span><span class="br0">&#93;</span> = <span class="nu0">27</span>;
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre><p>Note that <code>session-&gt;get()</code> returns an array, and it&#039;s returned by reference. You must assign session-variables by reference, like in this example.</p>
<p>This stores the value <code>27</code> in the session-based array <code>foo</code>, under the key <code>bar</code>. It is important that you don&#039;t mix Konstrukts way of handling sessions with legacy mechanisms (Eg. Never use <code>session_start</code> and similar functions or the <code>$_SESSION</code> variable).</p>
<h2>Abnormal responses</h2>
<p>Normally, you return strings from <code>execute()</code> and friends, which is then echoed out to the browser, at the end of the script. These are the normal cases, and are handled with a HTTP status-code 200. There are times however, where you need to send special responses. One of the more common is a 404, which signifies that the URL doesn&#039;t exist. This is the kind of response, you would want to send in out above example, if the user requests an article, that doesn&#039;t exist. HTTP responses are implemented as exceptions. The benefit of exceptions is that they unwind the call stack, without compromising encapsulation.</p>
<p>Another commonly used HTTP response, is a redirect. Since this is such often used, there is a specific implementation to handle it -- <code>k_http_Redirect</code>. You could also use the generic <code>k_http_Response</code> with a status code of 303, and a <code>Location</code> header, the following way:</p>
<pre class="php"><span class="re0">$redirect</span> = <span class="kw2">new</span> k_http_Response<span class="br0">&#40;</span><span class="nu0">303</span><span class="br0">&#41;</span>;
<span class="re0">$redirect</span>-&gt;<span class="me1">setHeader</span><span class="br0">&#40;</span><span class="st0">&quot;Location&quot;</span>, <span class="re0">$this</span>-&gt;<span class="me1">url</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
<span class="kw1">throw</span> <span class="re0">$redirect</span>;</pre><p>But this is less verbose:</p>
<pre class="php"><span class="kw1">throw</span> <span class="kw2">new</span> k_http_Redirect<span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">url</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</pre><p>There is also a <code>k_http_Authenticate</code> class, for doing basic www-authentication. Other HTTP-codes have not been implemented as explicit classes, so you&#039;ll have to use the generic response, as shown above. You can find more in-depth information on the HTTP status-codes in the <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">specification</a>.</p>
<p>Another use for throwing HTTP responses, is if your application is largely a HTML application, but you need to respond to certain URLs in a different content-type. This could be file downloads, or inter-application data, such as JSON or XML. In these cases, you don&#039;t want the normal rendering stack to proceed, so instead, you&#039;ll create a specific response, and throw that.</p>
<div class="note">Note: One of the main goals of Konstrukt is to encapsulate code. You should <strong>never</strong> output directly to the client, using functions like <code>echo()</code>, <code>print()</code>, or <code>header()</code>. By doing so, you will break the fundamental principle behind Konstrukt.</div>
</body>
</html>